package com.example.application.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.infrastructure.persistence.po.SysUsers;
import com.example.infrastructure.security.JwtUtils;
import com.example.interfaces.dto.LoginRequest;
import com.example.interfaces.dto.LoginResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

/**
 * 认证服务
 */
@Slf4j
@Service
public class AuthService {
    
    @Autowired
    private SysUsersService sysUsersService;
    
    @Autowired
    private JwtUtils jwtUtils;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    private static final String SMS_CODE_PREFIX = "sms:code:";
    private static final String DEFAULT_SMS_CODE = "666666";
    
    /**
     * 账号密码登录
     */
    public LoginResponse loginByPassword(LoginRequest request) {
        // 查找用户（支持用户名、手机号、邮箱）
        SysUsers user = findUserByIdentifier(request.getIdentifier());
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 验证密码
        if (!passwordEncoder.matches(request.getPassword(), user.getPasswordHash())) {
            throw new RuntimeException("密码错误");
        }
        
        // 生成token
        String token = jwtUtils.generateToken(user.getId(), user.getUsername(), request.getLoginType());
        
        return LoginResponse.builder()
                .token(token)
                .userId(user.getId())
                .username(user.getUsername())
                .nickname(user.getNickname())
                .phone(user.getPhone())
                .email(user.getEmail())
                .loginType(request.getLoginType())
                .build();
    }
    
    /**
     * 手机号验证码登录
     */
    public LoginResponse loginBySms(LoginRequest request) {
        // 验证验证码
        if (!verifySmsCode(request.getPhone(), request.getSmsCode())) {
            throw new RuntimeException("验证码错误或已过期");
        }
        
        // 查找或创建用户
        SysUsers user = findOrCreateUserByPhone(request.getPhone());
        
        // 生成token
        String token = jwtUtils.generateToken(user.getId(), user.getUsername(), request.getLoginType());
        
        // 清除验证码
        redisTemplate.delete(SMS_CODE_PREFIX + request.getPhone());
        
        return LoginResponse.builder()
                .token(token)
                .userId(user.getId())
                .username(user.getUsername())
                .nickname(user.getNickname())
                .phone(user.getPhone())
                .email(user.getEmail())
                .loginType(request.getLoginType())
                .build();
    }
    
    /**
     * 发送短信验证码
     */
    public void sendSmsCode(String phone) {
        if (!StringUtils.hasText(phone)) {
            throw new RuntimeException("手机号不能为空");
        }
        
        // 检查发送频率（1分钟内只能发送一次）
        String key = SMS_CODE_PREFIX + phone;
        if (Boolean.TRUE.equals(redisTemplate.hasKey(key))) {
            throw new RuntimeException("验证码已发送，请稍后再试");
        }
        
        // 这里使用默认验证码，实际项目中应该调用短信服务
        String code = DEFAULT_SMS_CODE;
        
        // 存储验证码，5分钟过期
        redisTemplate.opsForValue().set(key, code, 5, TimeUnit.MINUTES);
        
        log.info("发送短信验证码到手机号: {}, 验证码: {}", phone, code);
    }
    
    /**
     * 验证短信验证码
     */
    private boolean verifySmsCode(String phone, String code) {
        String key = SMS_CODE_PREFIX + phone;
        String storedCode = (String) redisTemplate.opsForValue().get(key);
        return DEFAULT_SMS_CODE.equals(code) || code.equals(storedCode);
    }
    
    /**
     * 根据标识符查找用户
     */
    private SysUsers findUserByIdentifier(String identifier) {
        LambdaQueryWrapper<SysUsers> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUsers::getUsername, identifier)
               .or().eq(SysUsers::getPhone, identifier)
               .or().eq(SysUsers::getEmail, identifier);
        return sysUsersService.getOne(wrapper);
    }
    
    /**
     * 根据手机号查找或创建用户
     */
    private SysUsers findOrCreateUserByPhone(String phone) {
        LambdaQueryWrapper<SysUsers> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUsers::getPhone, phone);
        SysUsers user = sysUsersService.getOne(wrapper);
        
        if (user == null) {
            // 创建新用户
            user = new SysUsers();
            user.setUsername("user_" + phone);
            user.setPhone(phone);
            user.setNickname("用户" + phone.substring(phone.length() - 4));
            user.setPasswordHash(passwordEncoder.encode("123456")); // 默认密码
            sysUsersService.save(user);
        }
        
        return user;
    }
    
    /**
     * 登出
     */
    public void logout(String token) {
        jwtUtils.logout(token);
    }
    
    /**
     * 刷新token
     */
    public LoginResponse refreshToken(String token) {
        String newToken = jwtUtils.refreshToken(token);
        Long userId = jwtUtils.getUserIdFromToken(newToken);
        SysUsers user = sysUsersService.getById(userId);
        
        return LoginResponse.builder()
                .token(newToken)
                .userId(user.getId())
                .username(user.getUsername())
                .nickname(user.getNickname())
                .phone(user.getPhone())
                .email(user.getEmail())
                .loginType(jwtUtils.getLoginTypeFromToken(newToken))
                .build();
    }
}